/**
 * 
 */
package net.phoenix.repository.dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;

import javax.jcr.Binary;
import javax.jcr.RepositoryException;

import net.phoenix.repository.BasicNode;
import net.phoenix.repository.BasicSession;
import net.phoenix.repository.RepositoryRuntimeException;

/**
 * @author lixf
 * 
 */
public class BlobBinary implements Binary {
	private Blob blob;
	private BlobValueLoaderDao loader;
	private String table;
	private String column;

	public BlobBinary(String table, String column) {
		this.table = table;
		this.column = column;
	}

	public void attachNode(final BasicNode node) throws RepositoryException {
		loader = (BlobValueLoaderDao) ((BasicSession) node.getSession())
				.getDao(BlobValueLoaderDao.class);
		try {
			this.blob = loader.load(table, column, node.getID());
		} catch (SQLException e) {
			throw new RepositoryException(e);
		} catch (IOException e) {
			throw new RepositoryException(e);
		}
	}

	@Override
	public InputStream getStream() throws RepositoryException {
		if (this.blob == null)
			return null;
		try {
			return this.blob.getBinaryStream();
		} catch (SQLException e) {
			throw new RepositoryException(e);
		}

	}

	@Override
	public int read(byte[] b, long position) throws IOException,
			RepositoryException {
		InputStream bis = this.getStream();
		try {
			long size = getSize();
			long length = b.length;
			if (position + b.length > size)
				length = size - position;
			return bis.read(b, (int) position, (int) length);
		} finally {
			bis.close();
		}
	}

	@Override
	public long getSize() throws RepositoryException {
		try {
			return this.blob.length();
		} catch (SQLException e) {
			throw new RepositoryException(e);
		}
	}

	@Override
	public void dispose() {
		try {
			this.loader.close();
		} catch (SQLException e) {
			throw new RepositoryRuntimeException(e);
		}
	}

}
